package gogtp

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
	"strings"
)

type Connection struct {
	cmd    *exec.Cmd
	input  io.WriteCloser
	output io.ReadCloser
	error  io.ReadCloser
	parse  IParser
}

//创建AI连接
func NewConnection(cmd string, args ...string) (conn *Connection, err error) {
	conn = new(Connection)
	conn.cmd = exec.Command(cmd, args...)
	if conn.input, err = conn.cmd.StdinPipe(); err != nil {
		return
	}
	if conn.error, err = conn.cmd.StderrPipe(); err != nil {
		return
	}
	if conn.output, err = conn.cmd.StdoutPipe(); err != nil {
		return
	}
	if err = conn.cmd.Start(); err != nil {
		return
	}
	go func() {
		if err := conn.cmd.Wait(); err != nil {
			conn.parse.OutputF(fmt.Sprintf("? %s", err.Error()))
			conn.Close()
		}
	}()
	go conn.listenError()
	go conn.listenOut()
	return
}

// 根据字符串创建
func NewConnectionByStr(path string) (conn *Connection, err error) {
	s1 := strings.Fields(path)
	command := s1[0]
	return NewConnection(command, s1[1:]...)
}

//传入命令行
func (c *Connection) PostCommand(cmd string, parser IParser) error {
	c.parse = parser
	_, err := c.input.Write([]byte(fmt.Sprintf("%s\n", cmd)))
	return err
}
func (c *Connection) RemoveParse() {
	c.parse = nil
}
func (c *Connection) listenOut() {
	reader := bufio.NewReader(c.output)
	for {
		line, err := reader.ReadString('\n')
		if err != nil || io.EOF == err {
			return
		}
		if c.parse != nil {
			c.parse.OutputF(strings.TrimSpace(line))
		}
	}
}
func (c *Connection) listenError() {
	reader := bufio.NewReader(c.error)
	for {
		line, err := reader.ReadString('\n')
		if err != nil || io.EOF == err {
			return
		}
		if c.parse != nil {
			c.parse.ErrorF(line)
		}
	}
}

func (c *Connection) Close() {
	_ = c.output.Close()
	_ = c.input.Close()
	_ = c.error.Close()
}
